package org.ttitfly.workflow.engine;

import org.ttitfly.workflow.exception.ProcessRunException;

/**
 * 流程，由一组开始动作和一系列运行单元组成，各运行单元相互串接。一个运行单元运行完成之后必将触发调度后续运行单元运行，如此保证流程按照预期运行，
 * 若已没有处于活动的运行单元
 * ，则整个流程也就完成了，若还有父运行单元，还将触发父运行单元继续运行。流程属于人工运行单元，即运行后需要等待人工处理完毕才能进入关闭(
 * <code>CLOSED</code>)状态。
 * 
 * 其中开始动作必须指向一个运行单元，若执行该动作，将触发流程从该运行单元处开始运行。
 * 
 * @author 潘海春
 * @version 2009-8-31
 * @see Activity
 * @see RunUnit
 */
public interface Process extends RunUnit {

	/**
	 * 版本
	 * 
	 * @return
	 */
	float getVersion();

	/**
	 * 执行默认动作启动流程，默认动作由特殊的名称或者空名称标识，一个流程至多拥有一个默认动作，若没有找到默认动作，将抛出
	 * <code>ProcessRunException</code>。 若找到，将调用其{@link Action#execute()}
	 * 方法，并得到返回的后续单元名称。若有相关激活处理程序，将执行之。同时触发流程调度后续单元，流程便开始从该运行单元开始运行。
	 * 
	 * @throws ProcessRunException
	 *             1.找不到默认动作时 2.<code>Action</code>执行过程抛出的异常将被包装成本异常抛出。
	 * @see Action#execute()
	 */
	void start() throws ProcessRunException;

	/**
	 * 执行指定名字动作来启动流程，同一个流程不存在多个动作同名，若没有找到符合名称的动作，将抛出
	 * <code>ProcessRunException</code>。
	 * 
	 * @param actionName
	 *            动作名称
	 * @throws ProcessRunException
	 *             1.找不到动作时 2.<code>Action</code>执行过程抛出的异常将被包装成本异常抛出。
	 * @see #start()
	 * @see Action#execute()
	 */
	void start(String actionName) throws ProcessRunException;

	/**
	 * 执行活动的默认动作，同一个流程不存在多个活动同名，若没有找到符合名称的活动，将抛出
	 * <code>ProcessRunException</code>。 若找到，将调用其{@link Activity#execute()}
	 * 方法，该方法最终会决定将调用{@link #dispatch(String)}方法调度下一个运行单元，还是将调用
	 * {@link #checkComplete()}来检查是否流程完成。
	 * 
	 * @param activityName
	 *            活动名称
	 * @throws ProcessRunException
	 *             1.找不到活动时 2.<code>Activity</code>执行过程抛出的异常将被包装成本异常抛出。
	 * @see Activity#execute()
	 */
	void execute(String activityName) throws ProcessRunException;

	/**
	 * 执行活动的指名动作，同一个流程不存在多个活动同名，若没有找到符合名称的活动，将抛出
	 * <code>ProcessRunException</code>。
	 * 
	 * @param activityName
	 *            活动名称
	 * @param actionName
	 *            动作名称
	 * @throws ProcessRunException
	 *             1.找不到活动时 2.<code>Activity</code>执行过程抛出的异常将被包装成本异常抛出。
	 * @see #execute(String)
	 * @see Activity#execute(String)
	 */
	void execute(String activityName, String actionName)
			throws ProcessRunException;

	/**
	 * 调度指名的运行单元，同一个流程不存在多个运行单元同名，若没有找到符合名称的运行单元，将抛出
	 * <code>ProcessRunException</code>。否则将实例化一个新的运行单元，并调用其{@link #run()}方法。
	 * <p>
	 * 该方法通常由运行单元在执行完成后调用。
	 * </p>
	 * 
	 * @param runUnitName
	 *            运行单元名称
	 * @throws ProcessRunException
	 */
	void dispatch(String runUnitName) throws ProcessRunException;

	/**
	 * 检查是否已经运行完成，将询问所有的运行单元，是否有处于运行(<code>RUNNING</code>
	 * )状态的，如果有则立即返回。若没有则说明流程已全部完成，则将状态置之为关闭(<code>CLOSED</code>
	 * )，若有相关退出处理程序将执行之，若还有父活动，则应调用其execute方法触发父活动继续运行。
	 * <p>
	 * 该方法通常由运行单元在执行完成后无后续运行单元时调用。
	 * </p>
	 * 
	 * @throws ProcessRunException
	 */
	void checkComplete() throws ProcessRunException;

	/**
	 * 指示某个活动是否已经执行
	 * 
	 * @param activityName
	 * @return
	 */
	boolean isClosed(String activityName);

}
